<?php

class ES_ESService extends BaseService
{
    static public $es_db = NULL;
    private static $self = NULL;

    static public function instance()
    {
        if (self::$self == NULL) {
            self::$self = new self;
        }

        return self::$self;
    }

    //实例ES的sdk
    public function __construct()
    {
        $params      = Config::get('elasticsearch.elastic');
        self::$es_db = new Elasticsearch\Client($params);
    }

    /**
     * 打印json
     */
    static public function printfJson(array $params)
    {
        echo json_encode($params);die;
        dd(json_encode($params));
    }

    //获取ES index的时间后缀
    private static function getTimeSuffix($start_time, $end_time, $time_format, $esCreateDBTime)
    {

        $time_arr     = array();
        $start_time   = $start_time / 1000;
        $end_time     = $end_time / 1000;
        $createDBtime = mktime($esCreateDBTime[0], $esCreateDBTime[1], $esCreateDBTime[2], $esCreateDBTime[3], $esCreateDBTime[4], $esCreateDBTime[5]);
        if ($start_time <= (int)$createDBtime) {
            $start_time = $createDBtime;
        }
        if ($end_time < $createDBtime) return FALSE;

        $start_date  = date($time_format, $start_time);
        $end_date    = date($time_format, $end_time);
        $start_year  = substr($start_date, 0, 4);
        $end_year    = substr($end_date, 0, 4);
        $start_month = substr($start_date, -2);
        $end_month   = substr($end_date, -2);
        if ($start_date == $end_date) {
            array_push($time_arr, $start_date);
        } else if ($start_year == $end_year) {
            if (substr($start_month, 0, 1) == 0) $start_month = substr($start_month, -1, 1);
            if (substr($end_month, 0, 1) == 0) $end_month = substr($end_month, -1, 1);
            for ($i = 0; $i <= ($end_month - $start_month); $i++) {
                $month = $start_month + $i;
                if ($month < 10) $month = '0' . $month;
                array_push($time_arr, $start_year . $month);
            }
        } else if ($start_year != $end_year) {
            if (substr($start_month, 0, 1) == 0) $start_month = substr($start_month, -1, 1);
            if (substr($end_month, 0, 1) == 0) $end_month = substr($end_month, -1, 1);
            for ($i = 0; $i <= (12 - $start_month); $i++) {
                $month = $start_month + $i;
                if ($month < 10) $month = '0' . $month;
                array_push($time_arr, $start_year . $month);
            }
            for ($i = ($end_month - 1); $i >= 0; $i--) {
                $month = $end_month - $i;
                if ($month < 10) $month = '0' . $month;
                array_push($time_arr, $end_year . $month);
            }
        }

        return $time_arr;
    }

    /**
     * 获取ES的数据库元数据
     * @param      $service_type
     * @return array
     */
    static public function getIndex($service_type)
    {
        $table = isset(ServiceTypeEnum::$table[$service_type]) ? ServiceTypeEnum::$table[$service_type]
            : array('index' => null, 'type' => null);

        return $table;
    }

    /**
     * 获取所有code的index
     */
    public static function getCodeIndex($start_time = NULL, $end_time = NULL)
    {
        $time_format    = 'Ym';
        $esDBNamePrefix = ElasticSearchEnum::$codePrefixGroup;
        $index          = '';
        foreach ($esDBNamePrefix as $index_name) {
            $esCreateDBTime = explode(',', ElasticSearchEnum::$createIndexTime[$index_name]);
            if (!$time_arr = self::getTimeSuffix($start_time, $end_time, $time_format, $esCreateDBTime)) continue;
            foreach ($time_arr as $time_suffix) {
                $index .= $index_name . $time_suffix . ',';
            }
        }
        $index = rtrim($index, ',');

        return $index;
    }

    /**
     * 获取es facets 的时间刻度
     * @param $data
     * @param $start_time
     * @param $end_time
     * @param $type
     * @return array|bool
     */
    static public function getFacetsRangeTime($data, $start_time, $end_time, $type = 'facets')
    {
        if (!empty($data)) {
            $first = array_shift($data);
            //$min_time = $first['time']/1000;
            if ($type == 'facets') {
                $min_time = $first['time'];
            }
            if ($type == 'aggs') {
                $min_time = $first['key'];
            }

            $time_params = array(
                'start_time' => $start_time,
                'end_time'   => $end_time,
                'min_time'   => $min_time,
            );
            $range_time  = TimeRangeEnum::getTimeRange($time_params);

            return $range_time;
        }

        return FALSE;
    }

    /**
     * 获取ES中简单的过滤条件
     */
    static public function getEsAndFilter(array $params)
    {
        $filter                       = array();
        $filter['query']['match_all'] = new stdClass();
        foreach ($params as $method => $v) {
            foreach ($v as $property => $value) {
                $filter['filter']['and'][][$method][$property] = $value;
            }
        }

        return $filter;
    }

    /**
     * 获取ES中的Facets的date_histogram的组成
     */
    static function getEsFacetsDateHistogram(array $params)
    {
        $date_histogram              = new stdClass();
        $date_histogram->field       = $params['field'];
        $date_histogram->value_field = $params['value_field'];
        $date_histogram->interval    = $params['interval'];
        //$date_histogram->factor = 1000;
        $date_histogram->size = 1000; //默认得到1000条记录
        return $date_histogram;
    }

    /**
     * $values必须包含的属性是
     * start_time,end_time，db_type
     * 默认db类型是report
     * term方式过滤可以包含的属性：
     * account_id,app_id,target_id,target_type,service_type
     * $size可以指定结果条数
     * @param     $values
     * @param int $size
     * @throws
     */
    public function getConnAndFilter($values, $size = 0)
    {
        if (!is_object($values)) throw Exception('$values必须是对象');
        $termFields = array(
            'account_id',
            'app_id',
            'target_id',
            'target_type',
            'service_type',
            'service_qualifier',
            // 'noResp',//数据的响应类型：true是无数据，false是有数据
        );
        $term       = array();
        foreach ($termFields as $field) {
            /* if($field == 'noResp' && is_null($values->noResp))
             {
                 $term[$field] = false;  //默认取有数据的字段
             }*/
            if (isset($values->$field) && !is_null($values->$field)) {
                $term[$field] = $values->$field;
            }
        }
        $db_type = ElasticSearchEnum::REPORT;
        if (isset($values->db_type) || !is_null($values->db_type)) $db_type = $values->db_type;
        $db_info                = self::getIndex($values->service_type, $db_type, $values->start_time, $values->end_time);
        $params['index']        = $db_info['index'];
        $params['type']         = $db_info['type'];
        $params['body']['size'] = $size;

        //$term = array('account_id'=>$values->account_id,'target_id'=>$values->target_id,'service_type'=>$values->service_type);
        $range = array('collTime' => array('from' => $values->start_time, 'to' => $values->end_time));
        if (empty($term)) {
            $filter = self::getEsAndFilter(array('range' => $range));
        } else {
            $filter = self::getEsAndFilter(array('term' => $term, 'range' => $range));
        }
        $params['body']['query']['filtered'] = $filter;

        return $params;
    }

    /**
     * 获取线性图表数据的公共方法(aggregation方式)
     * $values包含属性说明:
     * value_field:指要聚合的字段
     *  （1）当查询层次指标聚合时：
     *      nested:是子聚合的字段名称，
     *      nest_aggs_field:是子聚合中要进行分组的字段名称
     *      nest_aggs_field_value：是子聚合中要进行分组的字段名称的值
     *      nest_fields：子聚合的字段名称（array格式）
     *      例子：$values->value_field = array(
     *                                  'nested'=>'nest_sub',
     *                                  'nest_aggs_field'=>'devName',
     *                                  'nest_aggs_field_value'=>'c',
     *                                  'nest_fields'=>array('total','used'));
     *  （2）当查询非层次指标聚合时：
     *      $values->value_field = array('total','used');用于$type = 'all'
     *      $values->value_field = array('aggs_field'=>'monitor','fields'=>array('total','used'));用于$type = 'assign';
     *      $values->value_field = array(
     *                           'nested' => 'nest_sub',
     *                          'filter_field'=>'monitorId',
     *                          'filter_group_value'=>array(array(1),array(2)),
     *                          'nest_filter_field'=>'requestId',
     *                          'nest_filter_field_value'=>94,
     *                          'nest_fields'=>array('isAvailable'),
     *                      );用于$type = 'all_group_nest_assign';
     *
     *       $values->value_field = array(
     *              'filter_field'=>'monitorId',
     *               'fields'=>array('isAvailable'),
     *               'filter_group_value'=>array(array(1,2),array(3,4))
     *               );用于$type = 'all_group';
     *              filter_field：是要过滤的字段；filter_group_value：过滤字段分组的值；fields：要统计的值
     * $type:类型
     *      (1).'nest_all' :是子聚合中的所有
     *      (2).'nest_assign':是子聚合中指定某个元素
     *      (3).'all' :是非子聚合中的所有
     *      (4).'assign':是非子聚合中指定某个元素
     *      (5).'all_group':是非子聚合中指定的分组
     *      (6).'all_group_nest_assign':是非子聚合中指定的分组并指定子分组中的一个分组
     *
     * labels:对应聚合字段要显示的名称 array('1分钟平均负载','5分钟平均负载','15分钟平均负载');
     * colors:对应的颜色 array('#A0C667','#a9dbff','#FF6B49');
     * prefix:对应单位
     * result_type:对应要处理的数据类型 'total':是聚合的总值，'avg':是聚合值的平均,'min':是聚合值的最小值,'max':是聚合值的最大值
     * operate_type:对聚合的值进行单位换算类型 'multiply':是乘，'divided':是除以
     * operate_value:对应单位换算的值
     */
    public function getChartLineByAggs($values, $type = 'all')
    {
        $returnData                                    = array();
        $interval                                      = TimeRangeEnum::getFactsInterval($values->start_time, $values->end_time);
        //$xKeyTimeFormat                                = TimeRangeEnum::getMorrisxKeyTimeFormat($values->start_time, $values->end_time);
        $xKeyTimeFormat                                = TimeRangeEnum::getEchatsxKeyTimeFormat($values->start_time, $values->end_time);
        $xLables                                       = TimeRangeEnum::getMorrisxLables($values->start_time, $values->end_time);
        $params                                        = $this->getConnAndFilter($values);
        $aggs                                          = array();
        $aggs['timeAgg']['date_histogram']['field']    = 'collTime';
        $aggs['timeAgg']['date_histogram']['interval'] = $interval;

        //层次指标聚合
        if ($type == 'nest_assign') {
            $nest_path             = $values->value_field['nested'];
            $nest_aggs_field       = $values->value_field['nest_aggs_field'];
            $nest_fields           = $values->value_field['nest_fields'];
            $nest_aggs_field_value = $values->value_field['nest_aggs_field_value'];

            $aggs['timeAgg']['aggs'][$nest_path]['nested']['path']                           = $nest_path;
            $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['terms']['field'] = $nest_path . '.' . $nest_aggs_field;
            $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['terms']['size']  = 0;
            foreach ($nest_fields as $field) {
                $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['aggs'][$field]['stats']['field'] = $nest_path . '.' . $field;
            }
            $params['body']['aggs'] = $aggs;
            //self::printfJson($params);
            try {
                $result = self::$es_db->search($params);
            } catch (Exception $e) {
                SeasLog::error('this is a logger:' . $e->getMessage());
                return FALSE;
            }

            $time_buckets = $result['aggregations']['timeAgg']['buckets'];
            if (!is_array($time_buckets) || count($time_buckets) < 1) return FALSE;
            $range_time = self::getFacetsRangeTime($time_buckets, $values->start_time, $values->end_time, 'aggs');

            $format_results = array();
            foreach ($time_buckets as $v) {
                $key_time = (int)($v['key'] / 1000);
                foreach ($v[$nest_path][$nest_aggs_field]['buckets'] as $k1 => $v1) {
                    foreach ($nest_fields as $field) {
                        $format_results[$key_time][$v1['key']][$field] = $v1[$field];
                    }
                }
            }

            foreach ($range_time as $time) {
                $temp_data         = array();
                $temp_data['time'] = date($xKeyTimeFormat, $time);
                if (isset($format_results[$time])) {
                    foreach ($nest_fields as $field) {
                        $temp_data[$field] = round($format_results[$time][$nest_aggs_field_value][$field]['avg'], 2);
                        if ($values->result_type == 'avg') {
                            $avg = is_null($format_results[$time][$nest_aggs_field_value][$field]['avg']) ? '-' : round($format_results[$time][$nest_aggs_field_value][$field]['avg'], 2);
                            $temp_data[$field] = $avg;
                        }
                        if ($values->result_type == 'total') {
                            $sum = is_null($format_results[$time][$nest_aggs_field_value][$field]['sum']) ? '-' : round($format_results[$time][$nest_aggs_field_value][$field]['sum'], 2);
                            $temp_data[$field] = $sum;
                        }
                        if ($values->result_type == 'min') {
                            $min = is_null($format_results[$time][$nest_aggs_field_value][$field]['min']) ? '-' : round($format_results[$time][$nest_aggs_field_value][$field]['min'], 2);
                            $temp_data[$field] = $min;
                        }
                        if ($values->result_type == 'max') {
                            $max = is_null($format_results[$time][$nest_aggs_field_value][$field]['max']) ? '-' : round($format_results[$time][$nest_aggs_field_value][$field]['max'], 2);
                            $temp_data[$field] = $max;
                        }
                        if (isset($values->operate_type)) {
                            if ($values->operate_type == 'multiply') $temp_data[$field] = $temp_data[$field] * $values->operate_value;
                            if ($values->operate_type == 'divided') $temp_data[$field] = round($temp_data[$field] / $values->operate_value, 2);
                        }
                    }
                } else {
                    foreach ($nest_fields as $field) {
                        $temp_data[$field] = '-';
                    }
                }
                $returnData['show_data'][] = $temp_data;
            }
            $returnData['xkey']    = 'time';
            $returnData['xLabels'] = $xLables;
            $returnData['ykeys']   = $nest_fields;
            $returnData['labels']  = $values->labels;
            $returnData['colors']  = $values->colors;
            $returnData['prefix']  = $values->prefix;

            return $returnData;
        } else if ($type == 'all') {

            foreach ($values->value_field as $field) {
                $aggs['timeAgg']['aggs'][$field]['stats']['field'] = $field;
            }

            $params['body']['aggs'] = $aggs;
            //self::printfJson($params);
            try {
                $result = self::$es_db->search($params);
            } catch (Exception $e) {
                SeasLog::error('this is a logger:' . $e->getMessage());
                return FALSE;
            }
            $time_buckets = $result['aggregations']['timeAgg']['buckets'];

            if (!is_array($time_buckets) || count($time_buckets) < 1) return FALSE;

            $range_time     = self::getFacetsRangeTime($time_buckets, $values->start_time, $values->end_time, 'aggs');
            $format_results = array();
            foreach ($time_buckets as $v) {
                $key_time = (int)($v['key'] / 1000);
                foreach ($values->value_field as $field) {
                    $format_results[$key_time][$field] = $v[$field];
                }
            }

            foreach ($range_time as $time) {
                $temp_data         = array();
                $temp_data['time'] = date($xKeyTimeFormat, $time);
                if (isset($format_results[$time])) {
                    foreach ($values->value_field as $k=>$field) {
                        if(isset($values->labelShow)){
                            $temp_data[$values->labelShow[$k]] = round($format_results[$time][$field]['avg'], 2);
                            if ($values->result_type == 'avg') $temp_data[$values->labelShow[$k]] = round($format_results[$time][$field]['avg'], 2);
                            if ($values->result_type == 'total') $temp_data[$values->labelShow[$k]] = round($format_results[$time][$field]['sum'], 2);
                            if (isset($values->operate_type)) {
                                if ($values->operate_type == 'multiply') $temp_data[$values->labelShow[$k]] = round($temp_data[$values->labelShow[$k]] * $values->operate_value);
                                if ($values->operate_type == 'divided') $temp_data[$values->labelShow[$k]] = round($temp_data[$values->labelShow[$k]] / $values->operate_value, 2);
                            }
                            continue;
                        }
                        $temp_data[$field] = round($format_results[$time][$field]['avg'], 2);
                        if ($values->result_type == 'avg') {
                            $avg = is_null($format_results[$time][$field]['avg']) ? '-' :round($format_results[$time][$field]['avg'], 2);
                            $temp_data[$field] = $avg;
                        }
                        if ($values->result_type == 'total') {
                            $sum = is_null($format_results[$time][$field]['sum']) ? '-' :round($format_results[$time][$field]['sum'], 2);
                            $temp_data[$field] = $sum;
                        }
                        if (isset($values->operate_type)) {
                            if ($values->operate_type == 'multiply') $temp_data[$field] = round($temp_data[$field] * $values->operate_value);
                            if ($values->operate_type == 'divided') $temp_data[$field] = round($temp_data[$field] / $values->operate_value, 2);
                        }
                    }
                } else {
                    if(isset($values->labelShow)){
                        foreach ($values->value_field as $k=>$field) {
                            $temp_data[$values->labelShow[$k]] = '-';
                        }
                    }
                    foreach ($values->value_field as $field) {
                        $temp_data[$field] = '-';
                    }
                }
                $returnData['show_data'][] = $temp_data;
            }
            $returnData['xkey']    = 'time';
            $returnData['xLabels'] = $xLables;
            $returnData['ykeys']   = $values->value_field;
            if(isset($values->labelShow)){
                $returnData['ykeys'] = $values->labelShow;
            }
            $returnData['labels']  = $values->labels;
            $returnData['colors']  = $values->colors;
            $returnData['prefix']  = $values->prefix;

            return $returnData;
        } else if ($type == 'nest_all') {

        } else if ($type == 'assign') {

        } else if ($type == 'all_group_nest_assign') {
            $nest_sub                = $values->value_field['nested'];
            $filter_field            = $values->value_field['filter_field'];
            $nest_fields             = $values->value_field['nest_fields'];
            $filter_group_value      = $values->value_field['filter_group_value'];
            $nest_filter_field       = $nest_sub . '.' . $values->value_field['nest_filter_field'];
            $nest_filter_field_value = $values->value_field['nest_filter_field_value'];

            foreach ($filter_group_value as $k => $filter_value) {
                $in_filter                                                                                                                = 'in_filter' . $k;
                $ykeys[]                                                                                                                  = $in_filter;
                $aggs['timeAgg']['aggs'][$in_filter]['filter']['terms'][$filter_field]                                                    = $filter_value;
                $aggs['timeAgg']['aggs'][$in_filter]['aggs']['devStats']['nested']['path']                                                = $nest_sub;
                $aggs['timeAgg']['aggs'][$in_filter]['aggs']['devStats']['aggs']['in_nest_filter']['filter']['terms'][$nest_filter_field] = $nest_filter_field_value;
                foreach ($nest_fields as $field) {
                    $aggs['timeAgg']['aggs'][$in_filter]['aggs']['devStats']['aggs']['in_nest_filter']['aggs'][$field]['stats']['field'] = $nest_sub . '.' . $field;
                }
            }

            $params['body']['aggs'] = $aggs; //self::printfJson($params);
            try {
                $result = self::$es_db->search($params);
            } catch (Exception $e) {
                SeasLog::error('this is a logger:' . $e->getMessage());
                return FALSE;
            }
            $time_buckets = $result['aggregations']['timeAgg']['buckets'];
            if (!is_array($time_buckets) || count($time_buckets) < 1) return FALSE;

            $range_time = self::getFacetsRangeTime($time_buckets, $values->start_time, $values->end_time, 'aggs');

            $format_results = array();
            foreach ($time_buckets as $v) {
                $key_time = (int)($v['key'] / 1000);
                foreach ($filter_group_value as $k1 => $v1) { //$v[$nest_path][$nest_aggs_field]['buckets']
                    $in_filter = 'in_filter' . $k1;
                    foreach ($nest_fields as $field) {
                        $format_results[$key_time][$in_filter][$field] = $v[$in_filter]['devStats']['in_nest_filter'][$field];
                    }
                }
            }

            foreach ($range_time as $time) {
                $temp_data         = array();
                $temp_data['time'] = date($xKeyTimeFormat, $time);
                if (isset($format_results[$time])) {
                    foreach ($filter_group_value as $k1 => $v1) {
                        $in_filter = 'in_filter' . $k1;
                        foreach ($nest_fields as $field) {
                            $temp_data[$in_filter] = round($format_results[$time][$in_filter][$field]['avg'], 2);
                            if ($values->result_type == 'avg') {
                                $avg = is_null($format_results[$time][$in_filter][$field]['avg']) ? '-' : round($format_results[$time][$in_filter][$field]['avg'], 2);
                                $temp_data[$in_filter] = $avg;
                            }
                            if ($values->result_type == 'total') {
                                $sum = is_null($format_results[$time][$in_filter][$field]['sum']) ? '-' : round($format_results[$time][$in_filter][$field]['sum'], 2);
                                $temp_data[$in_filter] = $sum;
                            }
                            if ($values->result_type == 'min') {
                                $min = is_null($format_results[$time][$in_filter][$field]['min']) ? '-' : round($format_results[$time][$in_filter][$field]['min'], 2);
                                $temp_data[$in_filter] = $min;
                            }
                            if ($values->result_type == 'max') {
                                $max = is_null($format_results[$time][$in_filter][$field]['max']) ? '-' : round($format_results[$time][$in_filter][$field]['max'], 2);
                                $temp_data[$in_filter] = $max;
                            }
                            if (isset($values->operate_type)) {
                                if ($values->operate_type == 'multiply') $temp_data[$in_filter] = $temp_data[$in_filter] * $values->operate_value;
                                if ($values->operate_type == 'divided') $temp_data[$in_filter] = round($temp_data[$in_filter] / $values->operate_value, 2);
                            }
                        }
                    }
                } else {
                    foreach ($filter_group_value as $k1 => $v1) {
                        $in_filter             = 'in_filter' . $k1;
                        $temp_data[$in_filter] = '-';
                    }
                }
                $returnData['show_data'][] = $temp_data;
            }
            $returnData['xkey']    = 'time';
            $returnData['xLabels'] = $xLables;
            $returnData['ykeys']   = $ykeys;
            $returnData['labels']  = $values->labels;
            $returnData['colors']  = $values->colors;
            $returnData['prefix']  = $values->prefix;

            return $returnData;
        } else if ($type == 'all_group') {
            $filter_field       = $values->value_field['filter_field'];
            $fields             = $values->value_field['fields'];
            $filter_group_value = $values->value_field['filter_group_value'];
            foreach ($filter_group_value as $k => $filter_value) {
                $in_filter                                                             = 'in_filter' . $k;
                $ykeys[]                                                               = $in_filter;
                $aggs['timeAgg']['aggs'][$in_filter]['filter']['terms'][$filter_field] = $filter_value;
                foreach ($fields as $field) {
                    $aggs['timeAgg']['aggs'][$in_filter]['aggs'][$field]['stats']['field'] = $field;
                }
            }
            $params['body']['aggs'] = $aggs; //self::printfJson($params);
            try {
                $result = self::$es_db->search($params);
            } catch (Exception $e) {
                SeasLog::error('this is a logger:' . $e->getMessage());
                return FALSE;
            }

            $time_buckets = $result['aggregations']['timeAgg']['buckets'];

            if (!is_array($time_buckets) || count($time_buckets) < 1) return FALSE;

            $range_time = self::getFacetsRangeTime($time_buckets, $values->start_time, $values->end_time, 'aggs');

            $format_results = array();
            foreach ($time_buckets as $v) {
                $key_time = (int)($v['key'] / 1000);
                foreach ($filter_group_value as $k1 => $v1) { //$v[$nest_path][$nest_aggs_field]['buckets']
                    $in_filter = 'in_filter' . $k1;
                    foreach ($fields as $field) {
                        $format_results[$key_time][$in_filter][$field] = $v[$in_filter][$field];
                    }
                }
            }

            foreach ($range_time as $time) {
                $temp_data         = array();
                $temp_data['time'] = date($xKeyTimeFormat, $time);
                if (isset($format_results[$time])) {
                    foreach ($filter_group_value as $k1 => $v1) {
                        $in_filter = 'in_filter' . $k1;
                        foreach ($fields as $field) {
                            $temp_data[$in_filter] = round($format_results[$time][$in_filter][$field]['avg'], 2);
                            if ($values->result_type == 'avg') {
                                $avg = is_null($format_results[$time][$in_filter][$field]['avg']) ? '-' : round($format_results[$time][$in_filter][$field]['avg'], 2);
                                $temp_data[$in_filter] = $avg;
                            }
                            if ($values->result_type == 'total') {
                                $sum = is_null($format_results[$time][$in_filter][$field]['sum']) ? '-' : round($format_results[$time][$in_filter][$field]['sum'], 2);
                                $temp_data[$in_filter] = $sum;
                            }
                            if ($values->result_type == 'min') {
                                $min = is_null($format_results[$time][$in_filter][$field]['min']) ? '-' : round($format_results[$time][$in_filter][$field]['min'], 2);
                                $temp_data[$in_filter] = $min;
                            }
                            if ($values->result_type == 'max') {
                                $max = is_null($format_results[$time][$in_filter][$field]['max']) ? '-' : round($format_results[$time][$in_filter][$field]['max'], 2);
                                $temp_data[$in_filter] = $max;
                            }
                            if (isset($values->operate_type)) {
                                if ($values->operate_type == 'multiply') $temp_data[$in_filter] = $temp_data[$in_filter] * $values->operate_value;
                                if ($values->operate_type == 'divided') $temp_data[$in_filter] = round($temp_data[$in_filter] / $values->operate_value, 2);
                            }
                        }
                    }
                } else {
                    foreach ($filter_group_value as $k1 => $v1) {
                        $in_filter             = 'in_filter' . $k1;
                        $temp_data[$in_filter] = '-';
                    }
                }
                $returnData['show_data'][] = $temp_data;
            }
            $returnData['xkey']    = 'time';
            $returnData['xLabels'] = $xLables;
            $returnData['ykeys']   = $ykeys;
            $returnData['labels']  = $values->labels;
            $returnData['colors']  = $values->colors;
            $returnData['prefix']  = $values->prefix;

            return $returnData;
        }
    }

    /**
     * 获取时间段范围内的最后一条数据的公共方法
     * $values->value_field 要获取的字段
     * 例子：$values->value_field = array('devName');
     */
    public function getLastTimeData($values)
    {
        $params                                                           = $this->getConnAndFilter($values);
        $aggs                                                             = array();
        $aggs['lastTime_hits']['top_hits']['sort'][]['collTime']['order'] = 'desc';
        $aggs['lastTime_hits']['top_hits']['_source']['include']          = $values->value_field;
        $aggs['lastTime_hits']['top_hits']['size']                        = 1;
        $params['body']['aggs']                                           = $aggs;
        //self::printfJson($params);
        try {
            $result = self::$es_db->search($params);
        } catch (Exception $e) {
            SeasLog::error('this is a logger:' . $e->getMessage());
            return FALSE;
        }

        if (empty($result['aggregations']['lastTime_hits']['hits']['hits'])) return FALSE;
        $source = $result['aggregations']['lastTime_hits']['hits']['hits'][0]['_source'];

        return $source;
    }

    /**
     * 获取子聚合的某些值的聚合统计
     * value_field:指要聚合的字段
     *    nested:是子聚合的字段名称
     *    nest_filter_field:子聚合过滤字段
     *    nest_filter_field_value:子聚合过滤字段的值
     *    nest_fields：子聚合的字段名称（array格式）
     * 例子：$values->value_field = array('nested'=>'nest_sub','nest_filter_field'=>'devName','nest_filter_field_value'=>'c','nest_fields'=>array('diskWrites','diskReads'));
     */
    public function getAssignNest($values)
    {
        $params                  = $this->getConnAndFilter($values);
        $aggs                    = array();
        $nest_sub                = $values->value_field['nested'];
        $nest_filter_field       = $values->value_field['nested'] . '.' . $values->value_field['nest_filter_field'];
        $nest_filter_field_value = $values->value_field['nest_filter_field_value'];
        $nest_fields             = $values->value_field['nest_fields'];

        $aggs['devStats']['nested']['path']                                          = $nest_sub;
        $aggs['devStats']['aggs']['in_filter']['filter']['term'][$nest_filter_field] = $nest_filter_field_value;
        foreach ($nest_fields as $field) {
            $aggs['devStats']['aggs']['in_filter']['aggs'][$field]['stats']['field'] = $nest_sub . '.' . $field;
        }
        $params['body']['aggs'] = $aggs;
        //self::printfJson($params);
        try {
            $result = self::$es_db->search($params);
        } catch (Exception $e) {
            SeasLog::error('this is a logger:' . $e->getMessage());

            return FALSE;
        }
        $in_filter = $result['aggregations']['devStats']['in_filter'];
        if (!is_array($in_filter) || count($in_filter) < 1) return FALSE;

        return $in_filter;
    }

    /**
     * 获取子匹配名称
     * $values->value_field中包含的值
     * nestd 是子聚合名称
     * nest_field 是子聚合分割字段
     * regex 是匹配的正则表达式
     * @param $values
     */
    public function getMatchNest($values)
    {
        $params     = $this->getConnAndFilter($values);
        $aggs       = array();
        $nest_sub   = $values->value_field['nested'];
        $nest_field = $values->value_field['nest_field'];
        $regex      = $values->value_field['regex'];

        $aggs['devStats']['nested']['path']                    = $nest_sub;
        $aggs['devStats']['aggs']['devName']['terms']['field'] = $nest_sub . '.' . $nest_field;
        $aggs['devStats']['aggs']['devName']['terms']['size']  = 0;
        $params['body']['aggs']                                = $aggs;
        //self::printfJson($params);
        $result                                                = self::$es_db->search($params);
        foreach ($result['aggregations']['devStats']['devName']['buckets'] as $v) {
            if (preg_match($regex, $v['key'])) return $v['key'];
        }
    }

    /**
     * 时间段内曲线图数据
     * $values包含属性说明:
     * value_field:指要聚合的字段
     *  （1）当查询层次指标聚合时：
     *      nested:是子聚合的字段名称，
     *      nest_aggs_field:是子聚合中要进行分组的字段名称
     *      nest_fields：子聚合的字段名称（array格式）
     *      例子：$values->value_field = array('nested'=>'nest_sub','nest_aggs_field'=>'devName','nest_fields'=>array('total','used'));
     *  （2）当查询非层次指标聚合时：
     *      $values->value_field = array('total','used');
     */
    public function getChartCurveByAggs($values)
    {
        $returnData                                    = array();
        $interval                                      = TimeRangeEnum::getCurveInterval($values->start_time, $values->end_time);
        $params                                        = $this->getConnAndFilter($values);
        $aggs                                          = array();
        $aggs['timeAgg']['date_histogram']['field']    = 'collTime';
        $aggs['timeAgg']['date_histogram']['interval'] = $interval;

        //层次指标聚合
        if (isset($values->value_field['nested'])) {
            $nest_path       = $values->value_field['nested'];
            $nest_aggs_field = $values->value_field['nest_aggs_field'];
            $nest_fields     = $values->value_field['nest_fields'];

            $aggs['timeAgg']['aggs'][$nest_path]['nested']['path']                           = $nest_path;
            $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['terms']['field'] = $nest_path . '.' . $nest_aggs_field;
            $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['terms']['size']  = 0;
            foreach ($nest_fields as $field) {
                $aggs['timeAgg']['aggs'][$nest_path]['aggs'][$nest_aggs_field]['aggs'][$field]['stats']['field'] = $nest_path . '.' . $field;
            }
            $params['body']['aggs'] = $aggs;
            try {
                $result = self::$es_db->search($params);
            } catch (Exception $e) {
                SeasLog::error('this is host_overview logger:' . $e->getMessage(), array(), 'host/overview');

                return FALSE;
            }

            $time_buckets = $result['aggregations']['timeAgg']['buckets'];
            if (empty($time_buckets)) return FALSE;
            foreach ($time_buckets as $v) {
                foreach ($v[$nest_path][$nest_aggs_field]['buckets'] as $k1 => $v1) {
                    foreach ($nest_fields as $field) {
                        $returnData[$v1['key']][$field][] = $v1[$field]['avg'];
                    }
                }
            }

            return $returnData;
        }
    }



} 